package com.tanhua.management.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.code.kaptcha.Producer;
import com.tanhua.management.mapper.AdminMapper;
import com.tanhua.management.pojo.Admin;
import com.tanhua.management.utils.UserThreadLocal;
import com.tanhua.management.vo.AdminVo;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
@PropertySource("classpath:application.properties")
public class AdminService {


    @Autowired
    private Producer producer;
    @Autowired
    private AdminMapper adminMapper;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Value("${jwt.secret}")
    private String secret;

    public Admin queryUserByToken(String token) {
        try {
            Map<String, Object> body = Jwts.parser()
                    .setSigningKey(secret)
                    .parseClaimsJws(token)
                    .getBody();
            Long id = Long.valueOf(body.get("id").toString());
            //通过id查询Admin
            QueryWrapper<Admin> queryWrapper = new QueryWrapper();
            queryWrapper.eq("id", id);
            return this.adminMapper.selectOne(queryWrapper);
        } catch (Exception e) {
            log.error("token解析异常", e);
        }
        return null;
    }

    /**
     * 用户登录
     *
     * @param username
     * @param password
     * @param verificationCode
     * @param uuid
     * @return
     */
    public String login(String username, String password, String verificationCode, String uuid) {
        try {
            //从redis中获取验证码
            String verificationCodeKey = this.redisTemplate.opsForValue().get(uuid);
            // 判断验证码是否过期
            if (!StringUtils.isNotEmpty(verificationCode)) {
                return null;
            }
            // 判断验证码是否正确
            if (!StringUtils.equalsIgnoreCase(verificationCode, verificationCodeKey)) {
                return null;
            }
            // 删除验证码
            this.redisTemplate.delete(uuid);
            QueryWrapper<Admin> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("username", username);
            queryWrapper.eq("password", password);
            Admin admin = this.adminMapper.selectOne(queryWrapper);

            // 对admin进行非空判断
            if (admin!= null) {
                Map<String, Object> map = new HashMap<>();
                map.put("id", admin.getId());

                // 生成token
                String token = Jwts.builder()
                        .setClaims(map) //payload，存放数据的位置，不能放置敏感数据，如：密码等
                        .signWith(SignatureAlgorithm.HS256, secret) //设置加密方法和加密盐
                        .setExpiration(new DateTime().plusHours(24).toDate()) //设置过期时间，24小时后过期
                        .compact();
                System.out.println(token);
                return token;


            }
        } catch (Exception e) {
            log.error("登录失败", e);
        }
        return null;
    }

    /**
     * 查询用户基本信息
     *
     * @return
     */
    public AdminVo adminfo() {
        //校验token并获得登录的用户信息
        Admin admin = UserThreadLocal.get();
        //非空判断
        if (admin == null) {
            return null;
        }
        AdminVo adminVo = new AdminVo();
        adminVo.setUid(admin.getId().toString());
        adminVo.setUsername(admin.getUsername());
        adminVo.setAvatar(admin.getAvatar());
        return adminVo;
    }

    /**
     * 获取图片验证码
     *
     * @param uuid
     * @param response
     * @return
     */
    public Boolean getVerification(String uuid, HttpServletResponse response) {
        try {
            //生产验证码
            String verificationCode = producer.createText();

            //kaptcha.textproducer.char.length=4


            //生产图片验证码
            BufferedImage img = producer.createImage(verificationCode);
            ServletOutputStream outputStream = response.getOutputStream();
            ImageIO.write(img, "jpg", outputStream);

            // 将验证码保存到redis中,有效期1分钟,键为uuid,值为verificationCode
            this.redisTemplate.opsForValue().set(uuid, verificationCode, 1, TimeUnit.MINUTES);
            return true;
        } catch (Exception e) {
            log.error("图片验证码生成失败~~~", e);
        }
        return false;
    }

}
